//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package project_requirement_api_serv

import (
	"context"
	"fmt"

	"atomgit.com/openlinksaas-org/api-server/api_common"
	"atomgit.com/openlinksaas-org/api-server/dao"
	"atomgit.com/openlinksaas-org/api-server/dao/issue_dao"
	"atomgit.com/openlinksaas-org/api-server/dao/project_dao"
	"atomgit.com/openlinksaas-org/api-server/dao/requirement_dao"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/events/events_requirement"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/events_api"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/project_requirement_api"
	"github.com/google/uuid"
	"go.mongodb.org/mongo-driver/mongo"
	"google.golang.org/protobuf/types/known/anypb"
)

func (apiImpl *ProjectRequirementApiImpl) addCreateRequirementEvent(
	sessionItem *dao.SessionDbItem,
	req *project_requirement_api.CreateRequirementRequest,
	projectItem *project_dao.ProjectInfoDbItem,
	requirementId string, nowTime int64) {
	eventData, err := anypb.New(&events_requirement.CreateRequirementEvent{
		RequirementId: requirementId,
		Title:         req.BaseInfo.Title,
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_REQUIRE_MENT,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_REQUIRE_MENT,
			RefId:           requirementId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectRequirementApiImpl) addUpdateRequirementEvent(
	sessionItem *dao.SessionDbItem,
	req *project_requirement_api.UpdateRequirementRequest,
	projectItem *project_dao.ProjectInfoDbItem,
	reqItem *requirement_dao.RequirementInfoDbItem,
	nowTime int64) {
	eventData, err := anypb.New(&events_requirement.UpdateRequirementEvent{
		RequirementId: req.RequirementId,
		OldTitle:      reqItem.BaseInfo.Title,
		NewTitle:      req.BaseInfo.Title,
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_REQUIRE_MENT,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_REQUIRE_MENT,
			RefId:           req.RequirementId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectRequirementApiImpl) addUpdateTagEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	reqItem *requirement_dao.RequirementInfoDbItem,
	nowTime int64,
	oldTagList, newTagList []*events_requirement.TagInfo) {
	eventData, err := anypb.New(&events_requirement.UpdateTagEvent{
		RequirementId: reqItem.RequirementId,
		Title:         reqItem.BaseInfo.Title,
		OldTagList:    oldTagList,
		NewTagList:    newTagList,
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_REQUIRE_MENT,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_REQUIRE_MENT,
			RefId:           reqItem.RequirementId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectRequirementApiImpl) addRemoveRequirementEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	reqItem *requirement_dao.RequirementInfoDbItem,
	nowTime int64) {
	eventData, err := anypb.New(&events_requirement.RemoveRequirementEvent{
		RequirementId: reqItem.RequirementId,
		Title:         reqItem.BaseInfo.Title,
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_REQUIRE_MENT,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_REQUIRE_MENT,
			RefId:           reqItem.RequirementId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectRequirementApiImpl) addCloseRequirementEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	reqItem *requirement_dao.RequirementInfoDbItem,
	nowTime int64) {
	eventData, err := anypb.New(&events_requirement.CloseRequirementEvent{
		RequirementId: reqItem.RequirementId,
		Title:         reqItem.BaseInfo.Title,
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_REQUIRE_MENT,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_REQUIRE_MENT,
			RefId:           reqItem.RequirementId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectRequirementApiImpl) addOpenRequirementEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	reqItem *requirement_dao.RequirementInfoDbItem,
	nowTime int64) {
	eventData, err := anypb.New(&events_requirement.OpenRequirementEvent{
		RequirementId: reqItem.RequirementId,
		Title:         reqItem.BaseInfo.Title,
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_REQUIRE_MENT,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_REQUIRE_MENT,
			RefId:           reqItem.RequirementId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectRequirementApiImpl) addSetKanoInfoEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	reqItem *requirement_dao.RequirementInfoDbItem,
	nowTime int64) {
	eventData, err := anypb.New(&events_requirement.SetKanoInfoEvent{
		RequirementId: reqItem.RequirementId,
		Title:         reqItem.BaseInfo.Title,
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_REQUIRE_MENT,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_REQUIRE_MENT,
			RefId:           reqItem.RequirementId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectRequirementApiImpl) addSetFourQInfoEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	reqItem *requirement_dao.RequirementInfoDbItem,
	nowTime int64) {
	eventData, err := anypb.New(&events_requirement.SetFourQInfoEvent{
		RequirementId: reqItem.RequirementId,
		Title:         reqItem.BaseInfo.Title,
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_REQUIRE_MENT,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_REQUIRE_MENT,
			RefId:           reqItem.RequirementId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectRequirementApiImpl) addLinkIssueEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	reqItem *requirement_dao.RequirementInfoDbItem,
	issueItem *issue_dao.IssueInfoDbItem,
	nowTime int64) {
	eventData, err := anypb.New(&events_requirement.LinkIssueEvent{
		RequirementId: reqItem.RequirementId,
		Title:         reqItem.BaseInfo.Title,
		IssueId:       issueItem.IssueId,
		IssueTitle:    issueItem.BasicInfo.Title,
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_REQUIRE_MENT,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_REQUIRE_MENT,
			RefId:           reqItem.RequirementId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectRequirementApiImpl) addUnlinkIssueEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	reqItem *requirement_dao.RequirementInfoDbItem,
	issueItem *issue_dao.IssueInfoDbItem,
	nowTime int64) {
	eventData, err := anypb.New(&events_requirement.UnlinkIssueEvent{
		RequirementId: reqItem.RequirementId,
		Title:         reqItem.BaseInfo.Title,
		IssueId:       issueItem.IssueId,
		IssueTitle:    issueItem.BasicInfo.Title,
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_REQUIRE_MENT,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_REQUIRE_MENT,
			RefId:           reqItem.RequirementId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}
